//
//  NetworkTools.swift
//  WeiBoSwift
//
//  Created by rong on 15/6/26.
//  Copyright © 2015年 rong. All rights reserved.
//

import UIKit
import AFNetworking

class NetworkTools: AFHTTPSessionManager {

    private static let instance: NetworkTools = {
        
        //Baseurl以'/'结尾
        let urlStr = "https://api.weibo.com/"
        let baseUrl = NSURL(string: urlStr)!
        
        let tools = NetworkTools(baseURL: baseUrl)
        tools.responseSerializer.acceptableContentTypes = NSSet(objects: "application/json", "text/json", "text/javascript", "text/plain") as! Set<String>
        
        return tools
    
    }()

    //全局的访问方法
    class func sharedNetworkTools() -> NetworkTools{
    
        return instance
    }
    
    // 发布文本微博（包括表情） update.json
    /*
    发送参数：
                   必选	    类型及范围	说明
    source	       false	string	   采用OAuth授权方式不需要此参数，其他授权方式为必填参数，数值为应用的AppKey。
    access_token   false	string	   采用OAuth授权方式为必填参数，其他授权方式不需要此参数，OAuth授权后获得。
    status	       true	    string	   要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
    visible	       false	int	       微博的可见性，0：所有人能看，1：仅自己可见，2：密友可见，3：指定分组可见，默认      为0。
    list_id	       false	string	   微博的保护投递指定分组ID，只有当visible参数为3时生效且必选。
    lat	           false	float	   纬度，有效范围：-90.0到+90.0，+表示北纬，默认为0.0。
    long	       false	float	   经度，有效范围：-180.0到+180.0，+表示东经，默认为0.0。
    annotations	   false	string	   元数据，主要是为了方便第三方应用记录一些适合于自己使用的信息，每条微博可以包含一个或者多个元数据，必须以json字串的形式提交，字串长度不超过512个字符，具体内容可以自定。
    rip	           false	string	   开发者上报的操作用户真实IP，形如：211.156.0.1。
    
    返回参数：
        返回结果  JSON示例
    */
    
    // 发布图片微博    upload.json
    /*
    
                  必选	类型及范围	  说明
    source        false	string      采用OAuth授权方式不需要此参数，其他授权方式为必填参数，数值为应用的AppKey。
    access_token  false	string      采用OAuth授权方式为必填参数，其他授权方式不需要此参数，OAuth授权后获得。
    status	      true	string      要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
    visible	      false	int         微博的可见性，0：所有人能看，1：仅自己可见，2：密友可见，3：指定分组可见，默认0。
    list_id	      false	string      微博的保护投递指定分组ID，只有当visible参数为3时生效且必选。
!!! pic	          true	binary      要上传的图片，仅支持JPEG、GIF、PNG格式，图片大小小于5M。
    lat	          false	float       纬度，有效范围：-90.0到+90.0，+表示北纬，默认为0.0。
    long	      false	float       经度，有效范围：-180.0到+180.0，+表示东经，默认为0.0。
    annotations	  false	string      元数据，主要是为了方便第三方应用记录一些适合于自己使用的信息，每条微博可以包含一个或者多个元数据，必须以json字串的形式提交，字串长度不超过512个字符，具体内容可以自定。
    rip           false	string      开发者上报的操作用户真实IP，形如：211.156.0.1。
    */
    
    
    func postStatus(text: String, image: UIImage?, finished:(error: NSError?)->()) {
        
       // assert(sharedUserAccount?.access_token != nil, "必须传入  token")
        
        print("要发布的微博信息是： \(text)")
        
        var params = accessToken()
        params["status"] = text
        
        //let params = ["access_token": sharedUserAccount!.access_token, "status":text]
        var urlString = "2/statuses/"
        
        if image == nil {
        
            urlString += "update.json"
            
            POST(urlString, parameters: params, success: { (_, JSON) -> Void in
                print(JSON)
                
                finished(error: nil)
                }) { (_, error) -> Void in
                    print(error)
                    finished(error: error)
            }
            
        } else {
            urlString += "upload.json"
            
            POST(urlString, parameters: params, constructingBodyWithBlock: { (formData) -> Void in
                
                let data = UIImagePNGRepresentation(image!)
                
                formData.appendPartWithFileData(data, name:"pic", fileName:"hello", mimeType: "application/octect-stream")
                
                }, success: { (_, _) -> Void in
                    finished(error: nil)
                }, failure: { (_, error) -> Void in
                    finished(error: error)
            })
        }
        
    }
    
    
    ///  加载数据
    /**
    since_id    若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0
    max_id      若指定此参数，则返回ID小于或等于max_id的微博，默认为0
    */
    
    // 微博上拉刷新 的 “bug” : 如果网速不好，滑到最后一个cell时， 如果没有加载出来，此时往回滑，再往下拉，就会出现重复加载
    // 解决方法： 加一个  正在加载数据标记
    private  var isLoadingData = false
    //加载数据
    func loadStatus(since_id: Int, max_id: Int, finished: (array: [[String: AnyObject]]?, error: NSError?) -> ()){
        
        //assert(sharedUserAccount != nil, "Status:loadStatus ==> 必须登录之后才能访问网络")
        
        if isLoadingData {
            
            print("正在加载数据...")
            return
        }
        
        var params = accessToken()//["access_token": sharedUserAccount!.access_token]
        
        if since_id > 0 {
            params["since_id"] = "\(since_id)"
        }
        
        //!!!!! since_id 和 max_id 不能同时为 0
        if max_id > 0 {
            params["since_id"] = "0"
            params["max_id"] = "\(max_id - 1)"
        }
        
        isLoadingData = true
        
        //发起网络请求，异步加载数据
        NetworkTools.sharedNetworkTools().GET("2/statuses/home_timeline.json", parameters: params, success: { (_, JSON) -> Void in
            
            self.isLoadingData = false
            
            //从结果中获取的模型数组
            if let array = JSON["statuses"] as? [[String: AnyObject]] {
                
                //获得微博的模型数组
                //let list = statuses(array)
                
                //这里面是异步缓存，所有有可能这里没执行完，就去界面布局回调block（finished）
                //应该是先缓存完所有图片对象后，再去 通知 布局界面，如果没有下载完，就不知道图像宽高，没法布局界面
               // cacheWebImages(list, finished: finished)
                
                // array就是拿到的微博数组，直接回调返回
                //finished(statues: list)
                
                finished(array: array, error: nil)
                
                return
            }
            
            //空数据，解析失败或者其他原因
            finished(array: nil, error: nil)
            
            }) { (_, error) -> Void in
                
                self.isLoadingData = false
                
                print(error)
                
                //回调通知错误
                finished(array: nil, error: error)
        }
        
    }
    
    // 私有辅助函数
    // 生成accessToken  字典
    private func accessToken() -> [String: String] {
        assert(sharedUserAccount != nil, "必须登录之后才能访问网络")
        
        return ["access_token": sharedUserAccount!.access_token]
    }

}
